package com.boot.ys.mybatisplus.utils;

import net.logstash.logback.encoder.org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.joda.time.DateTime;
import org.joda.time.DateTimeFieldType;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 时间工具类
 * Created by chenjunyi on 2017/12/21.
 */
public class DateUtil {

    /** 年月日：yyyyMMdd */
    public static final String DATE_PATTERN   = "yyyyMMdd";

    /** 时分秒：HHmmss */
    public static final String TIME_PATTERN   = "HHmmss";

    /** 年月日时分：yyyyMMddHHmm */
    public static final String MINUTE_PATTERN = "yyyyMMddHHmm";

    /** 年月日时分秒：yyyyMMddHHmmss */
    public static final String FULL_PATTERN   = "yyyyMMddHHmmss";

    /**
     * 计算一个日期的hhmmss对应的秒数
     * @param date 日期
     * @return hhmmss对应的秒数
     */
    public static int timeSeconds(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        int seconds = calendar.get(Calendar.HOUR_OF_DAY) * 3600;
        seconds += calendar.get(Calendar.MINUTE) * 60;
        seconds += calendar.get(Calendar.SECOND);
        return seconds;
    }

    /**
     * 获取当前时间中指定字段的时间数
     * @param date 时间
     * @param fieldType 要获取的字段类型
     * @return 时间数
     */
    public static long getFieldTime(Date date, DateTimeFieldType fieldType) {
        DateTime dateTime = new DateTime(date);
        return (long) dateTime.get(fieldType);
    }

    /**
     * 获取时间
     * @param day int
     * @return Date
     */
    public static Date getNextDay(int day) {
        Date date =getAccountDate();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        return calendar.getTime();
    }


    /**
     * 日期相加
     * @param date  Date
     * @param day int
     * @return Date
     */
    public static Date addDate(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(getMillis(date) + ((long) day) * 24 * 3600 * 1000);
        return c.getTime();
    }

    /**
     * 增加时间
     * @param date 时间
     * @param calendarField 时间格式
     * @param amount 间隔
     * @return 日期
     */
    public static Date addDate(Date date, int calendarField, int amount) {
        if (date == null) {
            throw new IllegalArgumentException("The date could not be null!");
        }
        if (amount == 0) {
            return date;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(calendarField, amount);
        return calendar.getTime();
    }

    /**
     * 日期相减(返回秒值)
     * @param date Date
     * @param date1 Date
     * @return int
     * @author
     */
    public static Long diffDateTime(Date date, Date date1) {
        return (Long) ((getMillis(date) - getMillis(date1)) / 1000);
    }


    public static long getMillis(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.getTimeInMillis();
    }

    /**
     * 给时间加上分钟数
     * @param minute 需要加的分钟数，如果是负数，则减去分钟数
     * @return
     */
    public static String addDateMinut(int minute,String pattern){
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.MINUTE, minute);//30分钟后的时间
        System.out.println(format.format(nowTime.getTime()));
        return format.format(nowTime.getTime());
    }

    /**
     * 将日期格式化为指定格式的字符串
     * @param date 日期
     * @param pattern 自定义格式
     * @return 格式化字符串
     */
    public static String format(Date date, String pattern) {
        if (date == null) {
            return null;
        }
        return new DateTime(date).toString(pattern);
    }

    /**
     * 将日期格式化为指定格式的日期
     * @param date 日期
     * @param pattern 自定义格式
     * @return 格式化日期
     */
    public static Date formatToDate(Date date, String pattern) {
        if (date == null) {
            return null;
        }
        DateTimeFormatter format = DateTimeFormat.forPattern(pattern);
        return DateTime.parse(new DateTime(date).toString(pattern), format).toDate();
    }

    /**
     * 将日期字符串格式化为指定格式的日期
     * @param date 日期字符串
     * @param pattern 自定义格式
     * @return 格式化日期
     */
    public static Date formatToDate(String date, String pattern) {
        if (StringUtils.isBlank(date) || StringUtils.isBlank(pattern)) {
            return null;
        }
        DateTimeFormatter format = DateTimeFormat.forPattern(pattern);
        return DateTime.parse(date, format).toDate();
    }

    /**
     * 得到几天前的时间
     * @param date 时间
     * @param day 几天
     * @return
     */
    public static String getDateBefore(Date date,String format ,int day){
        Calendar now =Calendar.getInstance();
        now.setTime(date);
        now.set(Calendar.DATE,now.get(Calendar.DATE)-day);
        return getNowDate(now.getTime(),format);
    }

    public static String getNowDate(Date date,String format) {

        return DateFormatUtils.format(date, format);
    }

    public static Calendar getCalendar(Date date){
        Calendar cal=Calendar.getInstance();
        cal.setTime(date);
        return cal;
    }

    /**
     * 取得当月天数
     * */
    public static int getCurrentMonthLastDay(Calendar a ){
        a.set(Calendar.DATE, 1);//把日期设置为当月第一天
        a.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
        return a.get(Calendar.DATE);
    }


    /**
     * 判断给出的某个时间是否在某个时间范围内，注意时间格式要一致
     *
     * @param nowTime 当前时间
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     * @author jqlin
     */
    public static boolean isWithinTimeScope(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }

        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取会计日期
     * Created by kz on 2018/5/22 11:14.
     */
    public static Date getAccountDate(){
        return new Date();
    }

    public static void main(String[] args) {
        System.out.println(isWithinTimeScope(new Date() ,
                DateUtil.formatToDate("2018-12-1","yyyy-MM-dd"),
                DateUtil.formatToDate("2018-12-30","yyyy-MM-dd")));
    }

    /**
     * 获取时间为多久前
     * @param date
     * @return
     */
    public static String getShortTime(Date date) {
        String shortString = null;
        long now = Calendar.getInstance().getTimeInMillis();
        if(date == null) {
            return shortString;
        }
        long delTime = (now - date.getTime()) / 1000;
        if (delTime > 365 * 24 * 60 * 60) {
            shortString = (int) (delTime / (365 * 24 * 60 * 60)) + "年前";
        } else if (delTime > 24 * 60 * 60) {
            shortString = (int) (delTime / (24 * 60 * 60)) + "天前";
        } else if (delTime > 60 * 60) {
            shortString = (int) (delTime / (60 * 60)) + "小时前";
        } else if (delTime > 60) {
            shortString = (int) (delTime / (60)) + "分钟前";
        } else if (delTime > 1) {
            shortString = delTime + "秒前";
        } else {
            shortString = "1秒前";
        }
        return shortString;
    }

    /**
     * 获取时分
     * @param time 时分秒数据 格式 00:00:01
     * @return 时分字符串
     * Created by kz on 2019/4/1 20:21.
     */
    public static String getHourMinute(String time){
        if(StringUtils.isBlank(time)){
            return "";
        }

        String arr[]  = time.split(":");
        if(arr.length == 3){
            return arr[0] + ":" + arr[1];
        } else {
            return time;
        }
    }

    /**
     * 获取两个时间的时间差
     * @param toDate：大的时间
     * @param fromDate：小的时间
     * @param unit：返回时间单位  minutes：分钟，hours：小时，days：天
     * @return  默认返回分钟
     * Created by kz on 2018/5/20 17:00.
     */
    public static int getTimeDifference(Date fromDate , Date toDate , String unit){
        SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        String fromDateStr = simpleFormat.format(fromDate);
        String toDateStr = simpleFormat.format(toDate);
        long from = 0;
        try {
            from = simpleFormat.parse(fromDateStr).getTime();
        } catch (ParseException e) {
            throw new IllegalArgumentException("日期格式错误 fromDateStr:" + fromDateStr);
        }
        long to = 0;
        try {
            to = simpleFormat.parse(toDateStr).getTime();
        } catch (ParseException e) {
            throw new IllegalArgumentException("日期格式错误 toDateStr:" + toDateStr);
        }

        if("minutes".equals(unit)){
            return (int) ((to - from)/(1000 * 60));
        } else if("hours".equals(unit)){
            return (int) ((to - from)/(1000 * 60 * 60));
        } else if("days".equals(unit)){
            return (int) ((to - from)/(1000 * 60 * 60 * 24));
        } else {
            return (int) ((to - from)/(1000 * 60));
        }
    }

    /**
     * 日期大小比较
     * @param date1
     * @param date2
     * @param format 日期格式
     * @return  1：date1大于date2，0：date1等于date2，-1：date1小于date2
     * Created by kz on 2018/8/2 15:57.
     */
    public static int compareTo(Date date1 , Date date2 , String format){
        if (date1 == null) {
            throw new IllegalArgumentException("The date1 could not be null!");
        }if (date2 == null) {
            throw new IllegalArgumentException("The date2 could not be null!");
        }if (format == null) {
            throw new IllegalArgumentException("The format could not be null!");
        }

        if("yyyy-MM-dd".equals(format)){
            date1 = formatToDate(date1 , format);
            date2 = formatToDate(date2 , format);
        }

        if(date1.getTime() == date2.getTime()){
            return 0;
        } else if(date1.getTime() > date2.getTime()){
            return 1;
        } else {
            return -1;
        }
    }


    /**
     * 获得当月1号零时零分零秒
     * @return
     */
    public static Date initDateByMonth(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }


}
